package com.ruoyi.common.filter;

import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;

@Component
public class TraceIdInterceptor implements HandlerInterceptor {

    private static final String TRACE_ID = "dd.trace_id";
    private static final String SPAN_ID = "dd.span_id";
    private static final String SERVICE_NAME = "dd.service";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {


        // Attempt to retrieve traceId and spanId from the request header
        String traceId = request.getHeader(TRACE_ID);
        String spanId = request.getHeader(SPAN_ID);

        // If not provided, generate new traceId and spanId
        if (traceId == null || traceId.isEmpty()) {
            traceId = UUID.randomUUID().toString();
        }
        if (spanId == null || spanId.isEmpty()) {
            spanId = UUID.randomUUID().toString();
        }else {
            spanId = spanId + ","+ UUID.randomUUID().toString();
        }


        // Inject TraceId and other context information into MDC
        //trace_id一般是分布式系统的第一次调用时产生的，如果涉及到多个系统的内部调用，trace_id会传到下一个系统。
        //下一个系统发现有传入的traceId，则不会自己生成，会直接使用
        MDC.put(TRACE_ID, traceId);
        //span_id一般是分布式系统的第一次调用时产生的，如果涉及到多个系统的内部调用，span_id会传到下一个系统。
        //下一个系统发现有传入的traceId，则会在传入的span_id后面平接自己生成的span_id作为实际使用的span_id使用
        MDC.put(SPAN_ID, spanId);
        //每个系统的名称
        MDC.put(SERVICE_NAME, "over_temperature_monitor");

        // Set TraceId in the response header for tracing purposes
        response.setHeader(TRACE_ID, traceId);

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        // Clear MDC context after request is processed
        MDC.clear();
    }
}
